﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Reflection;
using System.ComponentModel;
using System.Windows.Forms;
using System.Drawing;
using System.IO;
using System.Collections.Concurrent;

namespace KXmlUIControl
{
    public static class StaticTypes
    {
        public static ConcurrentDictionary<string, Image> DicImages = new ConcurrentDictionary<string, Image>();

        public static string ButtonImageFolder = "";

        public static string IconFolder = "";

        public static string ImageFolder = "";

        public static string FormBKGFolder = "";

        public static string PageGifFolder = "";

        public static string KeyboardFolder = "";

        public static string VoiceFolder = "";

        public static string XmlConfigFolder = "";

        public static T ToEnum<T>(this string str)
        {
            return (T)Enum.Parse(typeof(T), str);
        }

        public static void SetRootDirectory(string root)
        {           
            ImageFolder = root + @"\image\";
            ButtonImageFolder = root + @"\image\Button\";
            IconFolder = root + @"\image\Icon\";
            FormBKGFolder = root + @"\image\Window\";
            PageGifFolder = root + @"\image\Gif\";
            KeyboardFolder = root + @"\keyboard\";
            VoiceFolder = root + @"\voice\";
            XmlConfigFolder = root + @"\UI\";
        }

        /// <summary>  
        /// 生成反射过来的MethodInfo到指定类型的委托  
        /// </summary>  
        /// <typeparam name="T">EventArgs泛型类型</typeparam>  
        /// <param name="instance">当前对象</param>  
        /// <param name="method">需要转化为delegate的方法</param>  
        /// <returns></returns>  
        public static EventHandler<T> CreateDelegateFromMethodInfo<T>(Object instance, MethodInfo method) where T : EventArgs//约束泛型T只能是来自EventArgs类型的  
        {
            if (method == null)
                return null;
            Delegate del = Delegate.CreateDelegate(typeof(EventHandler<T>), instance, method);  
            EventHandler<T> mymethod = del as EventHandler<T>;  
            return mymethod;  
        }  
  
        /// <summary>  
        /// 生成反射过来的MethodInfo到指定类型的委托  
        /// </summary>  
        /// <typeparam name="T">EventHandle泛型类型</typeparam>  
        /// <param name="instance">当前对象</param>  
        /// <param name="method">需要转化为delegate的方法</param>  
        /// <returns></returns>  
        public static EventHandler CreateDelegateFromMethodInfoByDelegate<T>(Object instance, MethodInfo method)  
        {
            if (method == null)
                return null;
            Delegate del = Delegate.CreateDelegate(typeof(T), instance, method);  
            EventHandler mymethod = del as EventHandler;  
            return mymethod;  
        }

        public static Size GetSize(string value)
        {
            if (string.IsNullOrEmpty(value))
            {
                return Size.Empty;
            }
            int begin = value.IndexOf("(");
            int end = value.IndexOf(")");
            if (begin >= 0 && begin >= 0)
            {
                value = value.Substring(begin + 1, end - begin - 1);
            }
            string[] arr = value.Split(new char[]{','}, StringSplitOptions.RemoveEmptyEntries);
            if (arr.Length == 2)
            {
                int w = Convert.ToInt32(arr[0]);
                int h = Convert.ToInt32(arr[1]);
                return new Size(w, h);
            }
            return Size.Empty;
        }

        public static bool ConvertToBoolean(string tStr, bool defaultVal = true)
        {
            if (string.IsNullOrEmpty(tStr))
            {
                return defaultVal;
            }
            bool value = defaultVal;
            bool.TryParse(tStr, out value);
            return value;
        }

        public static int ConvertToInt32(string tStr, int defaultVal = 120)
        {
            if (string.IsNullOrEmpty(tStr))
            {
                return defaultVal;
            }
            int value = defaultVal;
            int.TryParse(tStr, out value);
            return value;
        }

        public static Color GetColor(string value)
        {
            if (string.IsNullOrEmpty(value))
            {
                return Color.Empty;
            }
            value = value.Trim();
            if (value.Contains("(") && value.Contains(")"))
            {
                int begin = value.IndexOf("(");
                int end = value.IndexOf(")");
                string realVal = value.Substring(begin + 1, end - begin - 1);
                string[] arr = realVal.Split(',');
                if (arr.Length == 3)
                {
                    int r = Convert.ToInt32(arr[0]);
                    int g = Convert.ToInt32(arr[1]);
                    int b = Convert.ToInt32(arr[2]);
                    return Color.FromArgb(r, g, b);
                }
                if (arr.Length == 4)
                {
                    int a = Convert.ToInt32(arr[0]);
                    int r = Convert.ToInt32(arr[1]);
                    int g = Convert.ToInt32(arr[2]);
                    int b = Convert.ToInt32(arr[3]);
                    return Color.FromArgb(a, r, g, b);
                }
            }
            if (!value.Contains(","))
            {
                KnownColor kCol;
                if (Enum.TryParse<KnownColor>(value, out kCol))
                {
                    return Color.FromKnownColor(kCol);
                }

                Type colorType = typeof(Color);
                PropertyInfo info = colorType.GetProperty(value, BindingFlags.Public | BindingFlags.Static);
                if (info != null)
                {
                    return (Color)info.GetValue(null, null);
                }

                Type colorType1 = typeof(System.Drawing.SystemColors);
                PropertyInfo info1 = colorType1.GetProperty(value, BindingFlags.Public | BindingFlags.Static);
                if (info1 != null)
                {
                    return (Color)info1.GetValue(null, null);
                }
            }
            else
            {
                string[] array = value.Split(',');
                if (array.Length == 3)
                {
                    int r = Convert.ToInt32(array[0]);
                    int g = Convert.ToInt32(array[1]);
                    int b = Convert.ToInt32(array[2]);
                    return Color.FromArgb(r, g, b);
                }
                if (array.Length == 4)
                {
                    int a = Convert.ToInt32(array[0]);
                    int r = Convert.ToInt32(array[1]);
                    int g = Convert.ToInt32(array[2]);
                    int b = Convert.ToInt32(array[3]);
                    return Color.FromArgb(a, r, g, b);
                }
            }
            return Color.Empty;
        }

        private static Font GetFont(string[] values)
        {
            string fontName = values[0];
            string fontSize = values[1];
            if (fontSize.EndsWith("F") || fontSize.EndsWith("f"))
            {
                fontSize = fontSize.Substring(0, fontSize.Length - 1);
            }
            float size = 12f;
            float.TryParse(fontSize, out size);
            FontStyle style = FontStyle.Regular;
            if (values.Length == 3)
            {
                string fontStyle = values[2];
                if(fontStyle.Contains("|"))
                {
                    string[] styles = fontStyle.Split('|');
                    foreach(string sty in styles)
                    {
                        string value = sty.Trim();
                        style |= (FontStyle)Enum.Parse(typeof(FontStyle), value);
                    }
                }
                else
                {
                    style = (FontStyle)Enum.Parse(typeof(FontStyle), fontStyle);
                }               
            }
            return new Font(fontName, size, style);       
        }

        public static Font GetFont(string value)
        {
            if (string.IsNullOrEmpty(value))
            {
                return null;
            }
            if (value.Contains("(") && value.Contains(")"))
            {
                int begin = value.IndexOf("(");
                int end = value.IndexOf(")");
                string realVal = value.Substring(begin + 1, end - begin - 1);
                string[] arr = realVal.Split(',');
                if (arr.Length == 3 || arr.Length == 2)
                {
                    return GetFont(arr);
                }
            }
            string[] array = value.Split(',');
            if (array.Length == 3 || array.Length == 2)
            {
                return GetFont(array);
            }             
            return null;
        }

        private static Point GetLocation(string[] values)
        {
            int x = Convert.ToInt32(values[0]);
            int y = Convert.ToInt32(values[1]);
            return new Point(x, y);
        }

        public static Point GetLocation(string value)
        {
            if (string.IsNullOrEmpty(value))
            {
                return Point.Empty;
            }
            if (value.Contains("(") && value.Contains(")"))
            {
                int begin = value.IndexOf("(");
                int end = value.IndexOf(")");
                string realVal = value.Substring(begin + 1, end - begin - 1);
                string[] arr = realVal.Split(',');
                if (arr.Length == 2)
                {
                    return GetLocation(arr);
                }
            }
            string[] array = value.Split(',');
            if (array.Length == 2)
            {
                return GetLocation(array);
            }
            return Point.Empty;
        }

        public static Image GetImage(string file)
        {
            if (DicImages.ContainsKey(file))
            {
                return DicImages[file];
            }
            if (File.Exists(file))
            {
                Image image = Image.FromFile(file);
                if(!DicImages.TryAdd(file, image))
                {
                    return DicImages[file];
                }
                else
                {
                    return image;
                }            
            }
            return null;
        }

        public static Image GetButtonImage(string value)
        {
            string file = Path.Combine(ButtonImageFolder, value);
            return GetImage(file);
        }

        public static Image GetWindowImage(string value)
        {
            string file = Path.Combine(FormBKGFolder, value);
            return GetImage(file);        
        }

        public static Image GetPageGifImage(string value)
        {
            string file = Path.Combine(PageGifFolder, value);
            return GetImage(file);        
        }

        public static Image GetIconImage(string value)
        {
            string file = Path.Combine(IconFolder, value);
            return GetImage(file);
        }
    }
}